﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;
using AutoMapper;
using ViewRes;
using YuYuKiCms.Bl.Attribute;
using YuYuKiCms.Bl.Interface;
using YuYuKiCms.Framework.Interface;
using YuYuKiCms.Model;

namespace YuYuKiCms.Internet.Controllers
{
    [Authorize]
    public class PageController : Controller
    {
        private readonly IPageBL _pageBL;
        private readonly IUtil _util;

        public PageController(IPageBL pageBL, IUtil util)
        {
            _pageBL = pageBL;
            _util = util;
        }

        //
        // GET: /Page/
        [DynamicLayout]
        public ActionResult Index()
        {
            ViewBag.menu = RenderMenuHtml();
            return View();
        }

        //
        // GET: /PageController/
        [DynamicLayout]
        public ActionResult Create()
        {
            ViewBag.Title = Home.Create;
            Session["page_url"] = string.Empty;
            return View();
        }

        //
        // POST: /PageController/
        [HttpPost]
        [ValidateAntiForgeryToken]
        [DynamicLayout]
        public ActionResult Create(PageVm page)
        {
            if (ModelState.IsValid)
            {
                _pageBL.AddPage(page);

                return RedirectToAction("Index");
            }

            // If we got this far, something failed, redisplay form
            ModelState.AddModelError("", Page.creation_page_error);
            return View();
        }

        [HttpPost]
        public JsonResult Save(string list)
        {
            if (Request.IsAuthenticated && Request.IsAjaxRequest())
            {
                _pageBL.SaveMenu(list);
                return Json(true, JsonRequestBehavior.AllowGet);
            }

            return Json(false, JsonRequestBehavior.AllowGet);
        }

        //
        // POST: /PageController/

        [HttpPost]
        public MvcHtmlString Delete(int id)
        {
            if (Request.IsAjaxRequest())
            {
                _pageBL.DeletePage(id);

                return RenderMenuHtml();
            }
            return new MvcHtmlString(string.Empty);
        }

        [DynamicLayout]
        public ActionResult Edit(int id)
        {
            var pageMenu = _pageBL.GetById(id);

            if (null != pageMenu)
            {
                var p = Mapper.Map<PageVm>(pageMenu);
                Session["page_url"] = p.UrlTitle;
                ViewBag.Title = Home.Update;
                return View(p);
            }
            return RedirectToAction("Index");
        }

        //
        // POST: /PageController/

        [DynamicLayout]
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(PageVm menu)
        {
            _pageBL.UpdatePage(menu);
            return RedirectToAction("Index");
        }

        [ChildActionOnly]
        [AllowAnonymous]
        public ActionResult PageMenu()
        {
            return View(new MvcHtmlString(RenderMenuItem(GetMenuForShow)));
        }

        private MvcHtmlString RenderMenuHtml()
        {
            return new MvcHtmlString(RenderMenuItem(GetMenuForEdit, typeList: "ol"));
        }

        private string RenderMenuItem(Func<PageVm, string, string, string, string> f, string classMenu = null,
            string style = null,
            int? parentId = null,
            string typeList = "ul")
        {
            var lst = _pageBL.GetChildren(parentId)
                .ToList();

            if (!lst.Any())
                return string.Empty;

            var builder = new StringBuilder();

            var controller = _util.GetRouteData("controller");
            var action = _util.GetRouteData("action");
            var url = _util.GetRouteData("url");

            var tag = new TagBuilder(typeList);
            if (!string.IsNullOrWhiteSpace(classMenu))
                tag.AddCssClass(classMenu);

            if (!string.IsNullOrWhiteSpace(style))
                tag.Attributes.Add("style", style);

            foreach (var page in lst)
            {
                builder.Append(f(page, controller, action, url));
            }

            if (parentId == null)
                return builder.ToString();

            tag.InnerHtml = builder.ToString();

            return tag.ToString();
        }

        private string GetMenuForShow(PageVm p, string controller, string action, string url)
        {
            var tagLi = new TagBuilder("li");
            var className = (!string.IsNullOrWhiteSpace(url) &&
                             url.Equals(p.UrlTitle, StringComparison.OrdinalIgnoreCase))
                ? "active"
                : string.Empty;

            tagLi.InnerHtml = HtmlHelper.GenerateLink(
                Request.RequestContext, RouteTable.Routes, p.Title, "LocalizeRoute", "ContentHtml", "Home",
                new RouteValueDictionary(new {url = p.UrlTitle}),
                string.IsNullOrWhiteSpace(className) ? null : new Dictionary<string, object> {{"class", className}})
                              + RenderMenuItem(GetMenuForShow, className, null, p.Id);

            return tagLi.ToString(TagRenderMode.Normal);
        }

        private string GetMenuForEdit(PageVm p, string controller, string action, string url)
        {
            return string.Format(
                @"<li id='list_{1}' data-id='{1}' class='dd-item dd3-item'>
                    <div class='dd-handle dd3-handle'>Drag</div>
                    <div class='dd3-content'>
                        <span class='title'>{0}</span>
                        <span class='task'>
                            <a itemid='{1}' href='{2}?id={1}' class='editIcon icon'></a>
                            <a itemid='{1}' href='{3}?id={1}' class='deleteIcon icon'></a>
                        </span>
                    </div>
                    {4}
                </li>", p.Title, p.Id, Url.Action("Edit"), Url.Action("Delete"),
                RenderMenuItem(GetMenuForEdit, parentId: p.Id, typeList: "ol", classMenu: "dd-list"));
        }
    }
}